/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package desktopapplication1;

/**
 *
 * @author Lora
 */
public class Subnet {

    public static final Integer CLASEINVALIDA = 0;
    
    public static final Integer CLASEA = 1;
    public static final Integer CLASEB = 2;
    public static final Integer CLASEC = 3;
    
    private Integer firstMask;
    private Integer secondMask;
    private Integer thirdMask;
    private Integer fourthMask;
    private Long numeroCompleto;
    private Boolean valido;
    private Integer clase;
    private Integer numeroBits;

    public Subnet() {
        firstMask = new Integer(255);
        secondMask = new Integer(255);
        thirdMask = new Integer(255);
        fourthMask = new Integer(192);
        multiplicar();
        validar();

    }

    public Subnet(Integer firstMask, Integer secondMask, Integer thirdMask, Integer fourthMask) {
        this();
        this.firstMask = firstMask;
        this.secondMask = secondMask;
        this.thirdMask = thirdMask;
        this.fourthMask = fourthMask;
        multiplicar();
        validar();
    }

    public Subnet(Integer numberBits) {
        this();
        this.numeroBits = numberBits;
        
        numeroCompleto = new Long(0);
        for(int i = 0; i < numberBits; i++){
             numeroCompleto = numeroCompleto + 
                    new Long(new Double(Math.pow(2, 31-i)).longValue());
        }
        dividir();
        return;
    }
    

    public Integer getFirstMask() {
        return firstMask;
    }

    public void setFirstMask(Integer firstMask) {
        this.firstMask = firstMask;
        multiplicar();
        validar();
    }

    public Integer getSecondMask() {
        return secondMask;
    }

    public void setSecondMask(Integer secondMask) {
        this.secondMask = secondMask;
        multiplicar();
        validar();
    }

    public Integer getThirdMask() {
        return thirdMask;
    }

    public void setThirdMask(Integer thirdMask) {
        this.thirdMask = thirdMask;
        multiplicar();
        validar();
    }

    public Integer getFourthMask() {
        return fourthMask;
    }

    public void setFourthMask(Integer fourthMask) {
        this.fourthMask = fourthMask;
        multiplicar();
        validar();
    }

    public void validar() {
        calculateNumeroBits();
        maskClass();
        valido = validarMask();
    }

    public Boolean validarMask() {
//        Long maskMenor = Long.lowestOneBit(getNumeroCompleto());
//        Long maskMayor = Long.bitCount(numeroCompleto);
//        Long xorMask = (maskMayor ^ new Long(0xFFFFFFFF));
//        xorMask = (xorMask*-1) - 1;
////        Long maskTotal = numeroCompleto + Long.reverseBytes(numeroCompleto);
////        Long.bitCount(clase);
        if (Long.bitCount(numeroCompleto) + Long.numberOfTrailingZeros(numeroCompleto) != 32  ||
                firstMask < 255 ||
                fourthMask > 252) {
            return false;
        }
        return true;
    }

    public void dividir() {
        Long numeroTemporal = getNumeroCompleto();
        
        fourthMask = new Long(numeroTemporal % 0x100).intValue();
        numeroTemporal = numeroTemporal / 0x100;
        
        thirdMask = new Long(numeroTemporal % 0x100).intValue();
        numeroTemporal = numeroTemporal / 0x100;
        
        secondMask = new Long(numeroTemporal % 0x100).intValue();
        numeroTemporal = numeroTemporal / 0x100;
        
        firstMask = new Long(numeroTemporal % 0x100).intValue();
        numeroTemporal = numeroTemporal / 0x100;
    }

    public void multiplicar() {
        numeroCompleto = new Long(fourthMask) +
                         new Long(thirdMask *  0x100) +
                         new Long(secondMask * 0x10000) +
                         (new Long(firstMask) * new Long(0x1000000));
    }

    public Integer getNumeroBits() {
        validar();
        return numeroBits;
    }

    public Boolean getValido() {
        validar();
        return valido;
    }

    public Long getNumeroCompleto() {
        return numeroCompleto;
    }

    public void setNumeroCompleto(Long numeroCompleto) {
        this.numeroCompleto = numeroCompleto;
        dividir();
        validar();
    }
    
    private void maskClass(){
        if(fourthMask >= 192 && fourthMask <= 252){
            clase = new Integer(CLASEC);
            
        }else if(thirdMask >= 192 && fourthMask <= 252){
            clase = new Integer(CLASEB);
            
        }else if(secondMask >= 192 && fourthMask <= 252){
            clase = new Integer(CLASEA);
        
        }else {
            clase = new Integer(CLASEINVALIDA);
        }
    }

    public Integer getClase() {
        validar();
        return clase;
    }
    
    private void calculateNumeroBits(){
        numeroBits = 32 - Long.numberOfTrailingZeros(getNumeroCompleto());
    }
}
